package Derivation;

import java.util.Vector;

import Basics.*;

public class TopDown 
{	
	Program p;
	
	ParseResultsTopDown parser;
	
	
	public TopDown () {}
	
	
	public TopDown (Program ip)
	{
		this.p = ip;
		this.parser =  new ParseResultsTopDown(ip);
	}
	
	
	
	public TopDown (Rule ... irs)
	{
		this.p = new Program(irs);
		this.parser = new ParseResultsTopDown(this.p);
	}


	public Program getP() 
	{
		return p;
	}


	public void setP(Program p) 
	{
		this.p = p;
	}


	public ParseResultsTopDown getParser() 
	{
		return parser;
	}


	public void setParser(ParseResultsTopDown parser) 
	{
		this.parser = parser;
	}


	/*************************************************************************************************************/
	/** Title: TopDownIteration																				
	/** Description: One iteration of top down with one atom			
	/*************************************************************************************************************/
	
	public void TopDownIteration (Atom instAtom)
	{
		parser.getAtomsToDerive().remove(instAtom);
		parser.getProgramDeriver().Reset();
		parser.getProgramDeriver().GetDerivationsForAtomTopDown(instAtom);
		Vector<Vector<Rule>> derivationsVec = parser.getProgramDeriver().getDerivationsVec();
		
		Vector<Vector<Atom>> bodiesOfInstRules = parser.getProv(instAtom, derivationsVec);
		
		parser.getProvenance().put(instAtom, bodiesOfInstRules);
		
		parser.AddToAtomsNeedToBeDerived(bodiesOfInstRules);
		
		parser.ClearProvenanceFromIrrelevantBodies();
	}
	
	
	
	/*************************************************************************************************************/
	/** Title: Run																				
	/** Description: Finds all possible ways to derive an atom			
	/*************************************************************************************************************/
	
	public void Run (Atom root)
	{
		parser.getAtomsToDerive().add(root);
		while (false == parser.getAtomsToDerive().isEmpty())
		{
			TopDownIteration(parser.getAtomsToDerive().firstElement());
		}
		
		parser.LeaveOnlyPossibleDerivations();
		parser.LeaveOnlyRelevantDerivations(root);
	}
	
}
